/**
 * 
 */
package moreHealthControl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import moreHealthModel.LookUpFileElement;
import moreHealthModel.Campus.CampusLocation;

/**
 * @author pramakrishnan
 *
 */

//This is an Engine which will Predict the students path based on a pre defined routes saved in a file and the total student journey.
public class StudentJrnyPatternLookUp {

ArrayList<LookUpFileElement> patternLookupFileList= new ArrayList<LookUpFileElement>(); 
ArrayList<PatternFoundArrayList> totalPredictionResultArray = new ArrayList<PatternFoundArrayList>();


//INTENT: Get the all the elements from the Pattern Look Up file. 
//PRE-CONDITION	:
	//1. There should be at least 2 set of location in the file. 
	//2. There should be no spaces at the End of file. 
//POST-CONDITION:
	//1. Generates an Array List of all the elements in the LookupFile.
	//2. 
public void getPatternLookupFileArrayList() throws FileNotFoundException{

	//Student Prediction look up text file. 
	String patternLookupFile = ".\\src\\StudentPattern.txt";
	
	BufferedReader br = null;
	int lookupFileElementIndex = 0;
	
	//keeps track of the line number passed in the file.
	String lookupFileElements = null;
	File f = null; 
	
	try{
			
	f = new File (patternLookupFile);
	FileInputStream fis = new FileInputStream(f);     
	br = new BufferedReader(new InputStreamReader(fis));	 
	
	//Keep adding the elements in the list until end of file is reached.
    while ( (lookupFileElements=br.readLine()) != null ) {
    	
    	//line number in the Student prediction look up file.
    	lookupFileElementIndex++;
        
    	//Add the pattern look up file element to an array
    	parsePatternLookupFileElement(lookupFileElements);
        
//    	//if a match is found then get the index of the match in the look up file array.
//        if (lookupFileElements.equals(studentLocationPoint)){
//        	
//        	matchFoundIndex = lookupFileElementIndex;
//        }
     }	
	}
	catch (IOException e) {
        // catch io errors from FileInputStream or readLine()
        System.out.println("Uh oh, got an IOException error!" + e.getMessage());

     } finally {
        // if the file opened okay, make sure we close it
        if (br != null) {
           try {
              br.close();
           } catch (IOException ioe) {
           }
        }

     }
     
//     return matchFoundIndex;
}


//INTENT: Get the all the elements from the Pattern Look Up file. 
//PRE-CONDITION	:
	//1. The student should have been to at least to 2 locations i.e. completeStudentJourney should have at least 2 elements. 
	//2. Consecutive location in the Journey list should not be duplicate i.e. if Location[0] =0,0 then location[1]!=0,0
//POST-CONDITION:
	//1. Return the total prediction-list for the student based on the Student Journey list.
public ArrayList<PatternFoundArrayList> PatternEngine (ArrayList<CampusLocation> completeStudentJourney) throws FileNotFoundException{
	
	//This will load the content of the pattern lookup file to an array. 
	getPatternLookupFileArrayList();
	
	//This will find the pattern for each pair of student location starting from the end.
	//For Ex. if ABCDEF is the initial parameter then :
	//Calc1: start from EF.
	//Calc2: start from DE
	//Calc3: start from CD so on....
	RecursionPatternCalculator(completeStudentJourney);
	
	//The total-prediction based on the complete studentJourney List.
	return totalPredictionResultArray;
}


//INTENT:	Predict the location the Student based on his last two positions. 
//			The pattern is found by recursing the total Student Journey and getting the last two elements. 
//PRE-CONDITION	:
	//1.	The student should have been to at least to 2 locations i.e. studentJourneyLocationList should have at least 2 elements. 
	//2.	Consecutive location in the Journey list should not be duplicate i.e. if Location[0] =0,0 then location[1]!=0,0
	//3.	The location1 (loc1) and location2 (loc2) should be within the grid dimension.
//POST-CONDITION:
	//1.	Return the total prediction-list for the student based on the Student Journey list.
	//2. 	Remove the last element from the studentJourneyLocationList before every Recursive call and only consider
	//		last two elements. 
public ArrayList<PatternFoundArrayList> RecursionPatternCalculator(ArrayList<CampusLocation> studentJourneyLocationList){
	
	//If the student has been to only 2 location that is AB then the prediction will be BA. 
	if (studentJourneyLocationList.size()==2){
		//base case
		String loc1 = Integer.toString(studentJourneyLocationList.get(0).getLocationLatitude()) + Integer.toString((studentJourneyLocationList.get(0).getLocationlongitude()));
		String loc2 = Integer.toString(studentJourneyLocationList.get(1).getLocationLatitude()) + Integer.toString((studentJourneyLocationList.get(1).getLocationlongitude()));
		
		//Find the prediction in the file and store the result for every 2 Location the Student has visited starting 
		//from the last. 
		totalPredictionResultArray.add(LocationPatternMatcher(loc1, loc2));
		System.out.print("I am in base \n");
	}
	
	else{
		int arraySize = studentJourneyLocationList.size()-1;
		
		//get last two location the student has been to.
		String loc1 = Integer.toString(studentJourneyLocationList.get(arraySize-1).getLocationLatitude()) + Integer.toString(studentJourneyLocationList.get(arraySize-1).getLocationlongitude());
		String loc2 = Integer.toString(studentJourneyLocationList.get(arraySize).getLocationLatitude()) + Integer.toString(studentJourneyLocationList.get(arraySize).getLocationlongitude());

		
		//find match in the pattern file and add the found pattern.
		totalPredictionResultArray.add(LocationPatternMatcher(loc1, loc2));
		
		//call recursively with all the elements except for the last element. 
		//For example if initial condition is ABCDEF then next condition will be ABCDE and then ABCD -->ABC-->AB
		studentJourneyLocationList.remove(studentJourneyLocationList.get(arraySize));
		RecursionPatternCalculator(studentJourneyLocationList);
		
	
	}
	
	//total-prediction list for every location-pair the student has been to.
	return totalPredictionResultArray;
	
}


//INTENT:	Finds the Match for the Location-Pair of the Student and predicts the pattern based on a predefined text file.  
//PRE-CONDITION	:
//1.	The student should have been to at least to one matching pair from the text file.
//2.	Consecutive location in the Journey list should not be duplicate i.e. if Location[0] =0,0 then location[1]!=0,0
//3.	The location1 (loc1) and location2 (loc2) should be within the grid dimension.
//POST-CONDITION:
//1.	Return the prediction-list for the current Location-Pair in the Student Journey list.
//2. 	
public PatternFoundArrayList LocationPatternMatcher(String loc1, String loc2){
	ArrayList<String> tempArrayList = new ArrayList<String>();
	
	//If the Location-Pair match is found then get all the consecutive elements from the file.
	boolean patternFound= false; 
		
	//traversing through the Lookup file.
	for (int i =0; i<=patternLookupFileList.size()-2; i++){
	
	//Current element in the Lookup file to be matched with the Student's Current location
	String lookPath1 = patternLookupFileList.get(i).getPathCoordinate();

	//found first match
	if (loc1.equals(lookPath1) || patternFound == true){
		
		//Next element in the Lookup file should match the second Coordinated of the the Location-Pair to complete the 
		//matching. 
		//Location-Pair means two sets of coordinates the Student has visited. 
		//For example: In the journey ABCDEF Location-Pair will be EF
		String lookPath2 = patternLookupFileList.get(i+1).getPathCoordinate();
		if (loc2.equals(lookPath2) || patternFound == true){
			
			//found match
			patternFound = true; 
			tempArrayList.add(patternLookupFileList.get(i+1).getPathCoordinate());
		}
	}

	}
	
	//if not matching is found then go back to where you started.
	if (patternFound==false){
		tempArrayList.add(loc2);
		tempArrayList.add(loc1);
		
	}
	//based on the two given location the computed prediction is added in the array.
	PatternFoundArrayList currentPredictionResult = new PatternFoundArrayList(tempArrayList, loc1, loc2);
	
	
	//total prediction for all the location pairs. 
	//System.out.print("Finished predicting for " + loc1 + " " + loc2 + " ");
	return currentPredictionResult;
}


//INTENT:	Parses the Look up file and separates relevant Path data. 
//PRE-CONDITION	:
//1.	There should be no blanks in the Look up file.
//2.	The file should be properly formatted i.e. the first two elements should be integer followed by space and 
//		location description. The location Description is optional.
//		For Example. [Location Coordinates] [OPTIONAL: LocationDescription]===> 00 Path1.
//3.	The location1 (loc1) and location2 (loc2) should be within the grid dimension.
//POST-CONDITION:
//1.	Return the pattern-list from the prediction look up file.
//2. 
//Add the predefined route to an Array list. 
public void parsePatternLookupFileElement(String pathPattern){	
	
	//The coordinate in the look up file. 
	String coordinateSubstring = pathPattern.substring(0, 2);
	
	//The description of the look up file. 
	String pathTypeSubstring = pathPattern.substring(2, pathPattern.length()).trim();
	
	//Bundle both the data above in an object
	LookUpFileElement pathInfo= new LookUpFileElement(coordinateSubstring, pathTypeSubstring);
	
	//Add the elements in an array for prediction calculation. 
	//Array is used to store this data because it is not efficient to open a file. 
	patternLookupFileList.add(pathInfo); 

		}

}
